package com.example.demo.controller;

import com.example.demo.entity.Userinfo;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

@RestController
public class UserController {

    private static final String SESSION_KEY = "USERINFO_SESSION_KEY";

    // @RequestMapping 支持 get、post 请求。如果要访问到方法上，必须加上 @RequestMapping
    // 1、实现连接
    // 当只有一个参数，不需要加 value，当有指定方法时要加上。
    @RequestMapping(value = "/say", method = RequestMethod.POST)  // 可以是一级路由，也可以是 N 级路由
    public String sayHi() {
        return "springmvc sayhi";
    }

    @PostMapping("/sayhello") // 只支持 post 请求，不支持 get 请求
    public String sayhello() {
        return "springmvc hello";
    }

    @GetMapping("/hi") // @GetMapping 只支持 get 请求，不支持 post 请求
    public String hi() {
        return "springmvc hi";
    }
    // 2. 获取参数-------------------------------------------------------------------------
    // 2.1.1 获取单个参数
    @RequestMapping("/sayhi1")
    public String sayHi(String name) { // 不传递 name 参数，那么此变量使用的是 String 的默认值 null
        return "hi " + name;
    }

    @RequestMapping("/sayhi2")
    public String sayhi2(Integer id) { // 不传递参数，使用 Integer（包装类） 的默认值 null
        if(id == null) return "参数有误";
        return "hi " + id;
    }

    @RequestMapping("/sayhi3")
    public String sayhi3(int id) { // 不传递参数，报错 --> 所以参数传递不要使用基础数据类型，使用包装类
        return "hi " + id;
    }

    @RequestMapping("/sayhi4")
    public String sayhi4(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.sendRedirect("http://www.javacn.site");
        return "hi " + request.getParameter("name");
    }

    // 2.1.2 获取多个参数
    @RequestMapping("/sayhi11")
    public String sayHi11(String name, String password) {
        return "name:" + name + " | password:" + password;
    }

    /**
      * 2.2 获取对象
      * @param userinfo
     * @return
     */
    @RequestMapping("/reg")
    public Object reg(Userinfo userinfo) { // 框架会实现自动的参数映射
        System.out.println(userinfo); // 拿到的对象只是普通格式的对象
        return userinfo;
    }

    /**
     * 3、获取 json 格式的对象
     * @param userinfo
     * @return
     */
    @RequestMapping("/reg3")
    // @RequestBody --> 接收 JSON 对象，要想拿到 json 格式的，必须加上 @RequestBody 注解
    public Object reg3(@RequestBody Userinfo userinfo) {
        System.out.println(userinfo);
        return userinfo;
    }

    /**
     * 4、获取 URL中参数 @PathVariable ，从基础的 URL中获取参数（？之前的参数），
     * 而不是从 URL的参数部分获取参数。参数比较少的情况下使用这种传参
     * @param name
     * @param password
     * @return
     */
    @RequestMapping("/reg4/{name}/{password}")
    public Object reg4(@PathVariable String name, @PathVariable("password") String password) {
        return "name=" + name + " | password=" + password;
    }
    @RequestMapping("/reg44/{name}/{pwd}")  // 参数名不同
    public Object reg44(@PathVariable String name,
                        @PathVariable(required = false, name = "pwd") String password) {
        return "name=" + name + " | password=" + password;
    }

    /**
     * 5、获取上传的⽂件 @RequestPart
     * @param file
     * @return
     */
    @RequestMapping("/myupload")
    public Object upload(@RequestPart("dog")MultipartFile file) {
        String fileName = UUID.randomUUID() +  // 文件名
                file.getOriginalFilename().substring( // substring 处理的是文件后缀
                        file.getOriginalFilename().lastIndexOf(".")); // . 之前的为文件名

        File saveFile = new File(
                "D:\\Y\\106\\rrich\\java-ee\\JavaEE_further\\" + fileName);
        try{
            file.transferTo(saveFile);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 6、获取 Cookie
     * @param java
     * @return
     */
    @RequestMapping("/getck")
    public Object getCk(@CookieValue(value = "java", required = false) String java) {
        return java;
    }

    /**
     * 7、存储 session
     * @param request
     */
    @RequestMapping("/setsess")
    public void doPostConstruct(HttpServletRequest request) {
        HttpSession session = request.getSession();
        session.setAttribute(SESSION_KEY,"zhangsan");
    }

    /**
     * 8、获取 session
     * @return
     */
    @RequestMapping("/getsess")
    public Object getSession(@SessionAttribute(SESSION_KEY) String name) {
        return "session -> " + name;
    }

    /**
     * 9、获取 header
     * @param ua
     * @return
     */
    @RequestMapping("/gethd")
    public Object getHeader(@RequestHeader("User-Agent")String ua) {
        return "header -> " + ua;
    }
// =========================================================================================================
    @RequestMapping("h1")
    public Object getH1() {
        return "<h1>我是h1</h1>";
    }

    @RequestMapping("/reg2")
    // 使⽤ @RequestParam 来重命名前后端的参数值。eg：前端传入 username，后端命名为 name
    /* 如果我们的实际业务前端的参数是⼀个⾮必传的参数，
       我们可以通过设置 @RequestParam 中的 required=false 来避免不传递时报错
        @RequestParam 是从 URL 参数部分的参数（？之后的）*/
    public Object reg(String name,@RequestParam(value = "username", required = false)
            String password) {
        return name + ":" + password;
    }



}
